/*!
 * \file StatHelper.hpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 数据统计辅助器头文件
 * 
 * \details 本文件定义了WonderTrader数据服务系统的统计辅助器类StatHelper：
 *          - 提供数据传输统计功能
 *          - 统计数据包接收和发送数量
 *          - 统计数据传输字节数
 *          - 支持多种统计类型（广播等）
 *          - 提供线程安全的统计信息更新和查询
 *          - 采用单例模式提供全局统计服务
 *          - 支持统计信息的原子操作
 *          - 提供统计标志和更新标志管理
 */
#pragma once
#include <boost/atomic.hpp>
#include <boost/interprocess/detail/atomic.hpp>

/**
 * @class StatHelper
 * @brief 数据统计辅助器类
 * 
 * @details StatHelper是WonderTrader数据服务系统的统计辅助器，负责：
 *          - 提供全局数据传输统计功能
 *          - 统计各种类型的数据包接收和发送情况
 *          - 记录数据传输的字节数统计
 *          - 支持多种统计类型的分类管理
 *          - 提供线程安全的统计信息更新机制
 *          - 支持统计信息的实时查询和获取
 *          - 采用单例模式确保全局唯一性
 *          - 使用读写锁保证并发访问安全
 * 
 * @note 该类采用单例模式，通过one()方法获取实例
 * @warning 统计信息更新时需要考虑数值溢出问题
 */
class StatHelper
{
public:
	/**
	 * @brief 获取单例实例
	 * @details 获取StatHelper的唯一实例
	 * @return StatHelper& 单例引用
	 */
	static StatHelper& one()
	{
		static StatHelper only;
		return only;
	}

public:
	/**
	 * @struct _StatInfo
	 * @brief 统计信息结构体
	 * @details 存储数据传输的统计信息
	 */
	typedef struct _StatInfo
	{
		uint32_t	_recv_packs;	/*!< 接收数据包数量 */
		uint32_t	_send_packs;	/*!< 发送数据包数量 */
		uint64_t	_send_bytes;	/*!< 发送字节数 */

		/**
		 * @brief 构造函数
		 * @details 初始化统计信息，设置默认值为0
		 */
		_StatInfo()
		{
			_recv_packs = 0;
			_send_bytes = 0;
			_send_packs = 0;
		}
	} StatInfo;

	/**
	 * @enum StatType
	 * @brief 统计类型枚举
	 * @details 定义不同的统计类型
	 */
	typedef enum
	{
		ST_BROADCAST	/*!< 广播统计类型 */
	} StatType;

	/**
	 * @enum UpdateFlag
	 * @brief 更新标志枚举
	 * @details 定义统计信息更新的标志位
	 */
	typedef enum 
	{
		UF_Recv		= 0x0001,	/*!< 接收更新标志 */
		UF_Send		= 0x0002	/*!< 发送更新标志 */
	} UpdateFlag;

public:
	/**
	 * @brief 更新统计信息
	 * @details 更新指定类型的统计信息
	 * @param sType 统计类型
	 * @param recvPacks 接收数据包数量
	 * @param sendPacks 发送数据包数量
	 * @param sendBytes 发送字节数
	 */
	void updateStatInfo(StatType sType, uint32_t recvPacks, uint32_t sendPacks, uint64_t sendBytes)
	{
		BoostWriteLock lock(_mutexes[sType]);
		StatInfo& sInfo = _stats[sType];
		sInfo._recv_packs += recvPacks;
		sInfo._send_packs += sendPacks;
		if(UINT64_MAX - sInfo._send_bytes < sendBytes)
			sInfo._send_bytes = sendBytes;
		else
			sInfo._send_bytes += sendBytes;
		
		uint32_t flag = 0;
		if (recvPacks > 0)
			flag |= UF_Recv;
		if (sendPacks > 0)
			flag |= UF_Send;
	}
	
	/**
	 * @brief 获取统计信息
	 * @details 获取指定类型的统计信息
	 * @param sType 统计类型
	 * @return StatInfo 统计信息副本
	 */
	StatInfo getStatInfo(StatType sType)
	{
		BoostReadLock lock(_mutexes[sType]);
		return _stats[sType];
	}

private:
	StatInfo		_stats[5];		/*!< 统计信息数组 */
	BoostRWMutex	_mutexes[5];	/*!< 读写锁数组 */
};

